/*
 *  Copyright (c) 2014 The CCP project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a Beijing Speedtong Information Technology Co.,Ltd license
 *  that can be found in the LICENSE file in the root of the web site.
 *
 *   http://www.yuntongxun.com
 *
 *  An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
package com.shycloud.mido.common.sms.sdk;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.shycloud.mido.common.sms.utils.CcopHttpClient;
import com.shycloud.mido.common.sms.utils.DateUtil;
import com.shycloud.mido.common.sms.utils.EncryptUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.AbstractHttpMessage;
import org.apache.http.util.EntityUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

/**
 * CloopenSmsSDK 云通联短信 SDK
 *
 * @author nianhua.jiang
 */
public class CloopenSmsSDK {

	private static final int REQUEST_GET = 0;
	private static final int REQUEST_POST = 1;
	private static final String TEMPLATESMS = "SMS/TemplateSMS";
	private static String SERVER_IP = "app.cloopen.com";
	private static String SERVER_PORT = "8883";
	//主账户ID
	private static String ACCOUNT_SID = "8a216da8747ac9820174947234ea1f1f";
	//账户授权令牌
	private static String ACCOUNT_TOKEN = "24fe90824e784abda6978351de36b489";
	//appId
	public static String App_ID = "8a216da8747ac9820174947235a11f26";
	public static String UTF8 = "UTF-8";

	/**
	 * 初始化服务地址和端口
	 *
	 * @param serverIP   必选参数 服务器地址
	 * @param serverPort 必选参数 服务器端口
	 */
	public void init(String serverIP, String serverPort) {
		if (isEmpty(serverIP) || isEmpty(serverPort)) {
			throw new IllegalArgumentException("必选参数:" + (isEmpty(serverIP) ? " 服务器地址 " : "") + (isEmpty(serverPort) ? " 服务器端口 " : "") + "为空");
		}
		SERVER_IP = serverIP;
		SERVER_PORT = serverPort;
	}

	/**
	 * 发送短信模板请求
	 *
	 * @param to         必选参数 短信接收端手机号码集合，用英文逗号分开，每批发送的手机号数量不得超过100个
	 * @param templateId 必选参数 模板Id
	 * @param datas      可选参数 内容数据，用于替换模板中{序号}
	 * @return
	 */
	public HashMap<String, Object> sendTemplateSMS(String to, String templateId, String[] datas) throws IOException {
		HashMap<String, Object> validate = accountValidate();
		if (validate != null) {
			return validate;
		}

		if ((isEmpty(to)) || (isEmpty(App_ID)) || (isEmpty(templateId))) {
			throw new IllegalArgumentException("必选参数:" + (isEmpty(to) ? " 手机号码 " : "") + (isEmpty(templateId) ? " 模板Id " : "") + "为空");
		}
		CcopHttpClient chc = new CcopHttpClient();
		CloseableHttpClient httpclient = null;
		try {
			httpclient = chc.registerSSL(SERVER_IP, "TLS", Integer.parseInt(SERVER_PORT), "https");
		} catch (Exception e1) {
			e1.printStackTrace();
			throw new RuntimeException("初始化httpclient异常" + e1.getMessage());
		}
		String result = "";
		try {
			HttpPost httppost = (HttpPost) getHttpRequestBase(1, TEMPLATESMS);

			JsonObject json = new JsonObject();
			json.addProperty("appId", App_ID);
			json.addProperty("to", to);
			json.addProperty("templateId", templateId);
			if (datas != null) {
				StringBuilder sb = new StringBuilder("[");
				for (String s : datas) {
					sb.append("\"" + s + "\"" + ",");
				}
				sb.replace(sb.length() - 1, sb.length(), "]");
				JsonParser parser = new JsonParser();
				JsonArray jarray = parser.parse(sb.toString()).getAsJsonArray();
				json.add("datas", jarray);
			}
			String requsetbody = json.toString();

			BasicHttpEntity requestBody = new BasicHttpEntity();
			requestBody.setContent(new ByteArrayInputStream(requsetbody.getBytes(UTF8)));
			requestBody.setContentLength(requsetbody.getBytes(UTF8).length);
			httppost.setEntity(requestBody);
			HttpResponse response = httpclient.execute(httppost);

			HttpEntity entity = response.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity, UTF8);
			}


			EntityUtils.consume(entity);
		} catch (IOException e) {
			e.printStackTrace();
			return getMyError("172001", "网络错误");
		} catch (Exception e) {
			e.printStackTrace();
			return getMyError("172002", "无返回");
		} finally {
			if (httpclient != null) {
				httpclient.close();
			}
		}


		try {
			return jsonToMap(result);
		} catch (Exception e) {

			return getMyError("172003", "返回包体错误");
		}
	}

	private HashMap<String, Object> jsonToMap(String result) {
		HashMap<String, Object> hashMap = new HashMap<String, Object>();
		JsonParser parser = new JsonParser();
		JsonObject asJsonObject = parser.parse(result).getAsJsonObject();
		Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
		HashMap<String, Object> hashMap2 = new HashMap<String, Object>();

		for (Entry<String, JsonElement> m : entrySet) {
			if ("statusCode".equals(m.getKey()) || "statusMsg".equals(m.getKey())) {
				hashMap.put(m.getKey(), m.getValue().getAsString());
			} else {
				if ("SubAccount".equals(m.getKey()) || "totalCount".equals(m.getKey())
						|| "token".equals(m.getKey()) || "downUrl".equals(m.getKey())) {
					if (!"SubAccount".equals(m.getKey())) {
						hashMap2.put(m.getKey(), m.getValue().getAsString());
					} else {
						try {
							if ((m.getValue().toString().trim().length() <= 2) && !m.getValue().toString().contains("[")) {
								hashMap2.put(m.getKey(), m.getValue().getAsString());
								hashMap.put("data", hashMap2);
								break;
							}
							if (m.getValue().toString().contains("[]")) {
								hashMap2.put(m.getKey(), new JsonArray());
								hashMap.put("data", hashMap2);
								continue;
							}
							JsonArray asJsonArray = parser.parse(m.getValue().toString()).getAsJsonArray();
							ArrayList<HashMap<String, Object>> arrayList = new ArrayList<HashMap<String, Object>>();
							for (JsonElement j : asJsonArray) {
								Set<Entry<String, JsonElement>> entrySet2 = j.getAsJsonObject().entrySet();
								HashMap<String, Object> hashMap3 = new HashMap<String, Object>();
								for (Entry<String, JsonElement> m2 : entrySet2) {
									hashMap3.put(m2.getKey(), m2.getValue().getAsString());
								}
								arrayList.add(hashMap3);
							}
							hashMap2.put("SubAccount", arrayList);
						} catch (Exception e) {
							JsonObject asJsonObject2 = parser.parse(m.getValue().toString()).getAsJsonObject();
							Set<Entry<String, JsonElement>> entrySet2 = asJsonObject2.entrySet();
							HashMap<String, Object> hashMap3 = new HashMap<String, Object>();
							for (Entry<String, JsonElement> m2 : entrySet2) {
								hashMap3.put(m2.getKey(), m2.getValue().getAsString());
							}
							hashMap2.put(m.getKey(), hashMap3);
							hashMap.put("data", hashMap2);
						}

					}
					hashMap.put("data", hashMap2);
				} else {

					JsonObject asJsonObject2 = parser.parse(m.getValue().toString()).getAsJsonObject();
					Set<Entry<String, JsonElement>> entrySet2 = asJsonObject2.entrySet();
					HashMap<String, Object> hashMap3 = new HashMap<String, Object>();
					for (Entry<String, JsonElement> m2 : entrySet2) {
						hashMap3.put(m2.getKey(), m2.getValue().getAsString());
					}
					if (hashMap3.size() != 0) {
						hashMap2.put(m.getKey(), hashMap3);
					} else {
						hashMap2.put(m.getKey(), m.getValue().getAsString());
					}
					hashMap.put("data", hashMap2);
				}
			}
		}
		return hashMap;
	}

	private HttpRequestBase getHttpRequestBase(int get, String action) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		String timestamp = DateUtil.dateToStr(new Date(), DateUtil.DATE_TIME_NO_SLASH);
		EncryptUtil eu = new EncryptUtil();
		String sig = "";
		String acountName = "";
		String acountType = "Accounts";

		acountName = ACCOUNT_SID;
		sig = ACCOUNT_SID + ACCOUNT_TOKEN + timestamp;
		String signature = eu.md5Digest(sig);

		String url = getBaseUrl().append("/" + acountType + "/").append(acountName).append("/" + action + "?sig=").append(signature).toString();
		HttpRequestBase mHttpRequestBase = null;
		if (get == REQUEST_GET) {
			mHttpRequestBase = new HttpGet(url);
		} else if (get == REQUEST_POST) {
			mHttpRequestBase = new HttpPost(url);
		}
		setHttpHeader(mHttpRequestBase);
		String src = acountName + ":" + timestamp;
		String auth = eu.base64Encoder(src);
		mHttpRequestBase.setHeader("Authorization", auth);
		return mHttpRequestBase;
	}


	private String getmethodName(String action) {
		if (action.equals(TEMPLATESMS)) {
			return "sendTemplateSMS";
		} else {
			return "";
		}
	}

	private void setHttpHeader(AbstractHttpMessage httpMessage) {
		httpMessage.setHeader("Accept", "application/json");
		httpMessage.setHeader("Content-Type", "application/json;charset=utf-8");
	}

	private StringBuffer getBaseUrl() {
		StringBuffer sb = new StringBuffer("https://");
		sb.append(SERVER_IP).append(":").append(SERVER_PORT);
		sb.append("/2013-12-26");
		return sb;
	}

	private boolean isEmpty(String str) {
		return (("".equals(str)) || (str == null));
	}

	private HashMap<String, Object> getMyError(String code, String msg) {
		HashMap<String, Object> hashMap = new HashMap<String, Object>();
		hashMap.put("statusCode", code);
		hashMap.put("statusMsg", msg);
		return hashMap;
	}

	private HashMap<String, Object> accountValidate() {
		if ((isEmpty(SERVER_IP))) {
			return getMyError("172004", "IP为空");
		}
		if ((isEmpty(SERVER_PORT))) {
			return getMyError("172005", "端口错误");
		}
		if ((isEmpty(ACCOUNT_SID))) {
			return getMyError("172006", "主帐号为空");
		}
		if ((isEmpty(ACCOUNT_TOKEN))) {
			return getMyError("172007", "主帐号令牌为空");
		}
		if ((isEmpty(App_ID))) {
			return getMyError("172012", "应用ID为空");
		}
		return null;
	}
}